package com.freesky.biz.icbc.service.impl;

import com.alibaba.fastjson2.JSON;
import com.freesky.biz.icbc.excel.TScanChannelExport;
import com.freesky.biz.icbc.excel.TScanUserExport;
import com.freesky.biz.icbc.mapper.ScanChannelMapper;
import com.freesky.biz.icbc.service.IScanChannelService;
import com.freesky.biz.icbc.service.IScanUserService;
import com.freesky.biz.utils.SeqUtil;
import com.freesky.common.constant.UserConstants;
import com.freesky.common.core.domain.AjaxResult;
import com.freesky.common.core.domain.TreeSelect;
import com.freesky.common.core.domain.entity.SysUser;
import com.freesky.common.core.domain.entity.TScanChannel;
import com.freesky.common.enums.ExportStatusEnum;
import com.freesky.common.utils.SecurityUtils;
import com.freesky.common.utils.StringUtils;
import com.freesky.common.utils.spring.SpringUtils;
import com.freesky.framework.web.domain.server.Sys;
import com.freesky.system.domain.TExportRecord;
import com.freesky.system.service.ITExportRecordService;
import com.freesky.system.task.SyncReport;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class ScanChannelServiceImpl implements IScanChannelService {

    private static final Logger logger = LoggerFactory.getLogger(ScanChannelServiceImpl.class);

    @Autowired
    private ITExportRecordService exportRecordService;

    @Autowired
    private SyncReport syncReport;


    @Autowired
    private ScanChannelMapper scanChannelMapper;

    @Override
    public List<TScanChannel> selectScanChannelList(TScanChannel scanChannel) {
        return scanChannelMapper.selectScanChannelList(scanChannel);
    }

    @Override
    public List<TreeSelect> selectScanChannelTreeList(TScanChannel scanChannel)
    {
        List<TScanChannel> depts = scanChannelMapper.selectScanChannelList(scanChannel);
        return buildScanChannelTreeSelect(depts);
    }


    @Override
    public TScanChannel selectScanChannelById(Long id) {
        return scanChannelMapper.selectScanChannelById(id);
    }

    @Override
    public List<TScanChannel> selectChildrenScanChannelById(Long channelId) {
        return null;
    }

    @Override
    public boolean hasChildByScanChannelId(Long channelId) {
        int result = scanChannelMapper.hasChildByScanChannelId(channelId);
        return result > 0;
    }

    @Override
    public boolean checkScanChannelExistUser(Long channelId) {
        int result = scanChannelMapper.checkScanChannelExistUser(channelId);
        return result > 0;
    }

    @Override
    public boolean checkScanChannelNameUnique(TScanChannel scanChannel) {
        Long channelId = StringUtils.isNull(scanChannel.getChannelId()) ? -1L : scanChannel.getChannelId();
        TScanChannel info = scanChannelMapper.checkScanChannelNameUnique(scanChannel.getChannelName(),
                scanChannel.getPid());
        if (StringUtils.isNotNull(info) && info.getChannelId().longValue() != scanChannel.getChannelId().longValue())
        {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    @Override
    public int insertScanChannel(TScanChannel scanChannel) {
        if(StringUtils.isNotEmpty(scanChannel.getPid())) {
            TScanChannel info = scanChannelMapper.selectScanChannelById(Long.parseLong(scanChannel.getPid()));
            if(info!=null) {
                scanChannel.setPids(info.getPids() + scanChannel.getPid() + ",");
            } else {
                scanChannel.setPids(scanChannel.getPid() + ",");
            }
        } else {
            scanChannel.setPid("0");
            scanChannel.setPids("0,");
        }

        scanChannel.setChannelId(Long.valueOf(SeqUtil.getSeqId()));
        return scanChannelMapper.insertScanChannel(scanChannel);
    }

    @Override
    public int updateScanChannel(TScanChannel scanChannel) {
        TScanChannel newParentDept = scanChannelMapper.selectScanChannelById(Long.parseLong(scanChannel.getPid()));
        TScanChannel oldDept = scanChannelMapper.selectScanChannelById(scanChannel.getChannelId());
        if (StringUtils.isNotNull(newParentDept) && StringUtils.isNotNull(oldDept))
        {
            String newAncestors = newParentDept.getPids()  + newParentDept.getChannelId() + ",";
            String oldAncestors = oldDept.getPids();
            scanChannel.setPids(newAncestors);
            updateScanChannelChildren(scanChannel.getChannelId(), newAncestors, oldAncestors);
        }
        int result = scanChannelMapper.updateScanChannel(scanChannel);
        return result;
    }

    public void updateScanChannelChildren(Long channelId, String newAncestors, String oldAncestors)
    {
        List<TScanChannel> children = scanChannelMapper.selectChildrenScanChannelById(channelId);
        for (TScanChannel child : children)
        {
            child.setPids(child.getPids().replaceFirst(oldAncestors, newAncestors));
        }
        if (children.size() > 0)
        {
            scanChannelMapper.updateScanChannelChildren(children);
        }
    }


    @Override
    public int deleteScanChannelById(Long id) {
        return scanChannelMapper.deleteScanChannelById(id);
    }

    @Override
    public List<TScanChannel> exportScanChannelList(TScanChannel scanChannel) {
        return scanChannelMapper.exportScanChannelList(scanChannel);
    }

    @Override
    public AjaxResult exportFile(TScanChannel scanChannel) {
        SysUser sysUser = SecurityUtils.getLoginUser().getUser();
        TExportRecord exportRecord = new TExportRecord();
        exportRecord.setId(SeqUtil.getSeqId());
        exportRecord.setBizType("SCAN_CHANNEL");
        exportRecord.setCreateBy(String.valueOf(sysUser.getUserId()));

        TExportRecord exportRecordSelect = exportRecordService.selectRecordExportByStatus(exportRecord);
        if (exportRecordSelect != null) {
            return AjaxResult.error("已经有下载任务");
        }

        exportRecord.setStatus(ExportStatusEnum.SUBMIT_WAIT.getValue());
        exportRecordService.insert(exportRecord);

        syncReport.exportFileMutilHeader(scanChannel, new TScanChannelExport(), IScanChannelService.class,
                "exportScanChannelList", "渠道管理",Long.parseLong(exportRecord.getId()),sysUser.getUserName());

        return AjaxResult.success();
    }


    public List<TreeSelect> buildScanChannelTreeSelect(List<TScanChannel> scanChannels) {
        List<TScanChannel> deptTrees = buildScanChannelTree(scanChannels);
        return deptTrees.stream().map(TreeSelect::new).collect(Collectors.toList());
    }

    public List<TScanChannel> buildScanChannelTree(List<TScanChannel> channels)
    {
        List<TScanChannel> returnList = new ArrayList<TScanChannel>();
        List<Long> tempList = channels.stream().map(TScanChannel::getChannelId).collect(Collectors.toList());
        for (TScanChannel scanChannel : channels)
        {
            // 如果是顶级节点, 遍历该父节点的所有子节点
            if (!tempList.contains(Long.parseLong(scanChannel.getPid()))) {
                recursionFn(channels, scanChannel);
                returnList.add(scanChannel);
            }
        }
        if (returnList.isEmpty())
        {
            returnList = channels;
        }
        return returnList;
    }

    /**
     * 递归列表
     */
    private void recursionFn(List<TScanChannel> list, TScanChannel t)
    {
        // 得到子节点列表
        //System.out.println(JSON.toJSONString(t));
        List<TScanChannel> childList = getChildList(list, t);
        t.setChildren(childList);
        for (TScanChannel tChild : childList)
        {
            if (hasChild(list, tChild))
            {
                recursionFn(list, tChild);
            }
        }
    }


    /**
     * 得到子节点列表
     */
    private List<TScanChannel> getChildList(List<TScanChannel> list, TScanChannel t)
    {
        List<TScanChannel> tlist = new ArrayList<TScanChannel>();
        Iterator<TScanChannel> it = list.iterator();
        while (it.hasNext())
        {
            TScanChannel n = (TScanChannel) it.next();
            //System.out.println("getChildList:"+JSON.toJSONString(n)+","+JSON.toJSONString(t));
            if (StringUtils.isNotEmpty(n.getPid()) && n.getPid().equalsIgnoreCase(String.valueOf(t.getChannelId())))
            {
                tlist.add(n);
            }
        }
        return tlist;
    }

    /**
     * 判断是否有子节点
     */
    private boolean hasChild(List<TScanChannel> list, TScanChannel t)
    {
        return getChildList(list, t).size() > 0;
    }

}
